package com.situ.firmadmin.aspect;

import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.core.util.URLUtil;
import cn.hutool.extra.servlet.JakartaServletUtil;
import cn.hutool.http.useragent.UserAgent;
import cn.hutool.http.useragent.UserAgentUtil;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.situ.firmadmin.annotation.Limit;
import com.situ.firmadmin.annotation.MyLog;
import com.situ.firmadmin.constants.RedisConstants;
import com.situ.firmadmin.pojo.OperLog;
import com.situ.firmadmin.pojo.User;
import com.situ.firmadmin.service.IUserService;
import com.situ.firmadmin.service.impl.UserServiceImpl;
import com.situ.firmadmin.util.PageResult;
import com.situ.firmadmin.util.Result;
import jakarta.servlet.http.HttpServletRequest;
import lombok.extern.log4j.Log4j2;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.*;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import java.lang.reflect.Method;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.temporal.ChronoUnit;
import java.util.Arrays;
import java.util.Date;
import java.util.Map;
import java.util.Objects;

@Log4j2
@Aspect
@Component
public class LimitAspect {
	
	@Autowired
	public IUserService userService;
	@Autowired
	private RedisTemplate redisTemplate;
	
	/**
	 * 日志切点
	 */
	@Pointcut("@annotation(com.situ.firmadmin.annotation.Limit)")
	public void limitAspect() {
	
	}
	
	/**
	 * 前置通知
	 *
	 * @param joinPoint
	 * @throws Throwable
	 */
	@Before(value = "limitAspect()")
	public void doBefore(JoinPoint joinPoint) throws Throwable {
		HttpServletRequest request = ((ServletRequestAttributes) Objects
				.requireNonNull(RequestContextHolder.getRequestAttributes())).getRequest();
		//参数
		String params= Arrays.toString(joinPoint.getArgs());
		User user = userService.getUser();
		if (user != null) {
			/*//该用户请求参数及路径校验
			//从防重放参数校验的Redis集合中看是否有key为用户id的
			Object requestUser = redisTemplate.opsForValue().get(user.getId());
			if(Objects.nonNull(requestUser)){
				//不为空则有参数请求
				//查找是否有该参数
				Integer requestParam=(Integer) redisTemplate.opsForHash().get(user.getId(),params);
				if(Objects.nonNull(requestParam)){
					//该参数有请求，判断请求次数
					
				}
			}*/
			int i = ObjectUtils.nullSafeHash(user.getId(), params);
			System.out.println("hash值："+i);
			
		}
		
		//---------添加代码---------------
		MethodSignature signature = (MethodSignature) joinPoint.getSignature();
		Method method = signature.getMethod();
		Limit limit = method.getAnnotation(Limit.class);
		if (!ObjectUtils.isEmpty(limit) && !ObjectUtils.isEmpty(limit.message())) {
		}
		//------------------------
		
	}
	
	/**
	 * 返回通知
	 *
	 * @param ret
	 */
	@AfterReturning(pointcut = "limitAspect()", returning = "ret")
	public void doAfterReturning(Object ret) {
	
	}
	
	/**
	 * 异常通知
	 *
	 * @param e
	 */
	@AfterThrowing(pointcut = "limitAspect()", throwing = "e")
	public void doAfterThrowable(Throwable e) {
	}
	
	/**
	 * 格式化参数
	 *
	 * @param parameterMap
	 * @return
	 */
	private String formatParams(Map<String, String[]> parameterMap) {
		if (parameterMap == null) {
			return null;
		}
		StringBuilder params = new StringBuilder();
		for (Map.Entry<String, String[]> param : (parameterMap).entrySet()) {
			if (params.length() != 0) {
				params.append("&");
			}
			params.append(param.getKey() + "=");
			if (StrUtil.endWithIgnoreCase(param.getKey(), "password")) {
				params.append("*");
			} else if (param.getValue() != null) {
				params.append(ArrayUtil.join(param.getValue(), ","));
			}
		}
		return params.toString();
	}
}
